
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 */

package com.huawei.demo.health.auth;

import java.util.function.Consumer;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.webkit.WebResourceRequest;
import android.webkit.WebView;
import android.webkit.WebViewClient;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.huawei.demo.health.OkHttpUtilCallback;
import com.huawei.health.demo.R;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * Huawei ID signing In and authorization By restful API
 *
 * @since 2020-09-23
 */
public class HealthKitCloudLogin extends AppCompatActivity {
    private static final String TAG = "HealthKitCloudLogin";

    // the app ID information generated by the Developer Alliance when creating the application
    private static final String CLIENT_ID = "{appid}";

    // the secret information generated by the Developer Alliance when creating the application
    private static final String CLIENT_SECRET = "{secret}";

    // The value of redirect_uri must be the same as the Redirect_URI registered by developer, this only for example.
    private static final String REDIRECT_URI = "http://www.example.com";

    // URL to query access token
    private static final String CLOUD_TOKEN = "https://oauth-login.cloud.huawei.com/oauth2/v3/token";

    /**
     * URL of Huawei ID signing In and authorization Health Kit scopes
     * The value of redirect_uri must be the same as the Redirect_URI registered by developer, this only for example.
     */
    private static String CLOUD_AUTH =
        "https://oauth-login.cloud.huawei.com/oauth2/v3/authorize?response_type=code&client_id=" + CLIENT_ID
            + "&redirect_uri=http%3a%2f%2fwww.example.com&scope=https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fheightweight.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fgoals.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Findex.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fstep.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fdistance.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fspeed.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fcalories.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fpulmonary.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fstrength.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Factivity.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Flocation.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fbodyfat.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fsleep.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fheartrate.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fstress.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Frelaxtraining.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fnutrition.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fhearthealth.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fbloodglucose.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fbloodpressure.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Foxygensaturation.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Fbodytemperature.both+https%3A%2F%2Fwww.huawei.com%2Fhealthkit%2Freproductive.both&access_type=offline&display=touch";

    // webview to html
    private WebView mWebView;

    // okhttp3 OkHttpClient to send request
    private OkHttpClient mClient = new OkHttpClient();


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_health_cloud_login);

        // init WebView config
        initWebView();
    }

    private void initWebView() {
        mWebView = this.findViewById(R.id.webView);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.getSettings().setUseWideViewPort(true);
        mWebView.getSettings().setSupportZoom(true);
        mWebView.getSettings().setLoadWithOverviewMode(true);
        mWebView.getSettings().setBuiltInZoomControls(true);
        mWebView.getSettings().setDisplayZoomControls(false);

        // Customize the WebViewClient and Override the shouldOverrideUrlLoading method to query AccessToken after
        // Huawei ID sign In success. It is used only in the sample code, in the actual scenario, this query can be
        // processed on the callback page.
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                Log.i(TAG, request.toString());
                String url = request.getUrl().toString();
                // Intercept redirect_uri to query access token.
                if (url.startsWith("http://www.example.com")) {
                    String code = request.getUrl().getQueryParameter("code");
                    queryAccessToken(code);
                    return true;
                }

                // others only call super method
                return super.shouldOverrideUrlLoading(view, request);
            }

        });
        mWebView.loadUrl(CLOUD_AUTH);
    }

    /**
     * Use the authorization code to generate the access token.
     *
     * @param code Authorization Code
     */
    private void queryAccessToken(String code) {
        // 1. Build access token request
        Request request = buildAtRequest(code);

        // 2. Sending an asynchronous HTTP Request to generate the access token, and build user-defined Callback for
        // response. This Callback init with an anonymous Consumer to get access token and start
        // HealthKitAuthCloudActivity for check HUAWEI Health authorization result.
        mClient.newCall(request).enqueue(new OkHttpUtilCallback(new Consumer<String>() {
            @Override
            public void accept(String response) {
                // Parse response to get access token
                JsonObject jsonObject = new JsonParser().parse(response).getAsJsonObject();
                String accessToken = jsonObject.get("access_token").getAsString();

                // Set accessToken result to HealthKitAuthCloudActivity
                Intent intent = new Intent();
                intent.putExtra("accessToken", accessToken);
                setResult(RESULT_OK, intent);
                finish();
            }
        }));
    }

    /**
     * Build restful request to generate the access token
     *
     * @param code Authorization Code from sign in HUAWEI ID
     * @return Request to generate the access token
     */
    private Request buildAtRequest(String code) {
        RequestBody requestBody = new FormBody.Builder().add("code", code)
            .add("grant_type", "authorization_code")
            .add("client_id", CLIENT_ID)
            .add("client_secret", CLIENT_SECRET)
            .add("redirect_uri", REDIRECT_URI)
            .build();

        return new Request.Builder().url(CLOUD_TOKEN)
            .header("Content-Type", "application/x-www-form-urlencoded")
            .post(requestBody)
            .build();
    }
}
